<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>列表无缝滚动</title>
</head>
<style>
  * {
    margin: 0;
    padding: 0;
  }

  div {
    width: 100px;
    height: 50px;
    overflow: hidden;
    margin: 50px auto;
    border: 1px solid #000;
    text-align: center;
  }

  div:hover {
    cursor: pointer;
  }

  /* 添加硬件加速 */
  #wrapper {
    transform: translateZ(0);
    will-change: scroll-position;
  }

  /* 优化列表渲染 */
  #content, #fakeContent {
    contain: content;
    backface-visibility: hidden;
  }
</style>

<body>
  <div id="wrapper">
    <ul id="content">
      <li>11111</li>
      <li>22222</li>
      <li>33333</li>
      <li>44444</li>
      <li>55555</li>
      <li>66666</li>
    </ul>
    <ul id="fakeContent"></ul>
  </div>

</body>
<script>
  const content = document.getElementById("content");
  const fakeContent = document.getElementById("fakeContent");
  const wrapper = document.getElementById("wrapper");

  const contentHeight = content.scrollHeight;
  fakeContent.innerHTML = content.innerHTML;

  wrapper.addEventListener('mouseenter', stopAnimation);
  wrapper.addEventListener('mouseleave', () => {
    startAnimation();
    // wrapper.scrollTop = 0;  // 增加复位逻辑
  });

  let animationId;
  // 添加惯性滚动效果
  let lastScrollTop = 0;
  let velocity = 0;
  // 开始滚动函数
  function rollStart() {
    const delta = wrapper.scrollTop - lastScrollTop;
    velocity = delta * 0.1; // 惯性系数
    lastScrollTop = wrapper.scrollTop;

    // wrapper.scrollTop += 1;
    wrapper.scrollTop += 1 + velocity;
    // 正常滚动不断给scrollTop的值+1,当滚动高度大于列表内容高度时恢复为0
    if (wrapper.scrollTop >= content.scrollHeight) {
      wrapper.scrollTop = 0;
    }
    animationId = requestAnimationFrame(rollStart);
  }

  function startAnimation() {
    cancelAnimationFrame(animationId);
    animationId = requestAnimationFrame(rollStart);
  }

  function stopAnimation() {
    cancelAnimationFrame(animationId);
  }

  function destroy() {
    cancelAnimationFrame(animationId);
    wrapper.removeEventListener('mouseenter', stopAnimation);
    wrapper.removeEventListener('mouseleave', startAnimation);
  }
</script>

</html>